package com.neusoft.utils.tpl.res;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.mozilla.javascript.EvaluatorException;

import com.neusoft.utils.encrypt.MD5Util;
import com.neusoft.utils.file.FileUtils;
import com.neusoft.utils.res.compressor.TResCompressorUtils;
import com.neusoft.utils.string.StringUtil;
import com.neusoft.utils.tpl.DirectiveUtils;
import com.neusoft.utils.tpl.bean.ResBean;
import com.neusoft.utils.tpl.bean.ResCacheBean;
import com.neusoft.utils.tpl.help.ReadJsonToMap;
import com.neusoft.utils.tpl.help.ResCache;
import com.neusoft.utils.web.RequestUtils;

import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateDirectiveModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateModel;

/**
 * 
 *
 * @author von_change@163.com
 * @date 2015年12月4日 下午12:56:41
 * @since 1.0
 */
public class JsAllMinDirective implements TemplateDirectiveModel {
	private String charset = "UTF-8";
	private String jsFolder ="/js/";// "nginx/files/enroll/res/js/";SystemConfig.getProperty("res.gen")+
	public static final String PARAM_SRC = "src";
	

	@SuppressWarnings({ "rawtypes", "unchecked" })
	public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException {
		String result = "";
		StringBuffer sb = new StringBuffer();
		StringBuffer identifySb=new StringBuffer();
		Long sumTime=new Long(0);
		String src = DirectiveUtils.getString(PARAM_SRC, params);
		HttpServletRequest req = RequestUtils.getRequest();
		String base = req.getContextPath();
		String thisUrl=RequestUtils.getUrl(req);
		Map<String, String> configMap = ReadJsonToMap.read(getFile(req,"commonConfig/js.json"));	
		String[] jsSrcs = src.split(",");
		List<ResBean> resList = new ArrayList<ResBean>();
		for (String jsStr : jsSrcs) {
			if (null == configMap.get(jsStr)) {
				String jsPath = RequestUtils.getWebRealPath(req,jsStr);
				File jsFile = new File(jsPath);
				if (!jsFile.exists()) {
					env.getOut().append(result);
					return;
				}
				Long time = jsFile.lastModified();
				resList.add(new ResBean().setPath(jsStr).setTime(time).setFile(jsFile));
				identifySb.append(jsStr);
				sumTime+=time;
			} else {
				String[] jsSubSrcs = configMap.get(jsStr).split(",");
				for (String jsSubSrc : jsSubSrcs) {
					String jsPath = RequestUtils.getWebRealPath(req,jsSubSrc);
					File jsFile = new File(jsPath);
					if (!jsFile.exists()) {
						env.getOut().append(result);
						return;
					}
					Long time = jsFile.lastModified();
					resList.add(new ResBean().setPath(jsSubSrc).setTime(time).setFile(jsFile));
					identifySb.append(jsStr);
					sumTime+=time;
				}
			}
		}
		boolean orgFlag = false;
		String s = req.getQueryString();
		if (null != s && !StringUtil.isBlank(s)) {
			if (s.endsWith("@")||ResCache.model.equals("debug")) {
				orgFlag = true;
			}
		}
		if (!orgFlag) {
			String thisUrlMd=MD5Util.getMD5(thisUrl);
			String md5 =thisUrlMd+"/"+ MD5Util.getMD5(identifySb.toString());
			String jsFilePath = jsFolder + md5 +"-"+sumTime.toString()+ ".js";
			File minJsFile = new File(RequestUtils.getWebRealPath(req,jsFilePath));
			if (!minJsFile.exists()) {
				for (ResBean resBean : resList) {
					//单独生成做缓存
					sb.append("/*! ").append(resBean.getPath()).append(" */").append("\r\n").append(getMinJs(resBean)).append("\r\n ");
				}
				String jsStr=sb.toString();
				FileUtils.writeStringToFile(minJsFile, jsStr, charset);	
			}
			result = StringUtil.format("<script src=\"{0}/{1}\"></script>\r\n", base, jsFilePath);
		} else {
			result = renderOrgJsList(resList, base);
		}
		env.getOut().append(result);
	}
	private String getMinJs(ResBean resBean){
		ResCacheBean resCacheBean=ResCache.resCacheMap.get(resBean.getPath());
		if(null==resCacheBean||resCacheBean.getTime().longValue()!=resBean.getTime().longValue()){
			//更新缓存
			String sb = "";
			try {
				sb = FileUtils.readFileToString(resBean.getFile(), charset);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			String jsStr="";
			if(resBean.getPath().endsWith(".min.js")){//min  直接读 不会进行压缩
				jsStr=sb.toString();
			}else{
				 try {
					jsStr=TResCompressorUtils.jsCompressor(sb+";");
				} catch (EvaluatorException | IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}    
			ResCache.resCacheMap.put(resBean.getPath(), new ResCacheBean().setContent(jsStr).setTime(resBean.getTime()));
		}
		return ResCache.resCacheMap.get(resBean.getPath()).getContent();
	}
	private String renderOrgJsList(List<ResBean> resList, String base) {
		StringBuffer resultSb = new StringBuffer();
		for (ResBean resBean : resList) {
			resultSb.append(StringUtil.format("<script src=\"{0}/{1}?v={2}\"></script>", base, resBean.getPath(), resBean.getTime().toString())).append("\r\n");
		}
		return resultSb.toString();
	}


	private File getFile(HttpServletRequest req,String path) {
		return new File(RequestUtils.getWebRealPath(req,path));
	}

}
